#include "useHead.h"
#include "funcTable.h"

int FuncTable::getEntryPoint(int index)
{
    if (index < 0 || index >= _vf.size())
        return -1;

    return _vf[index]._entryPoint;
}


int FuncTable::getParamCount(int index)
{
    if (index < 0 || index >= _vf.size())
        return -1;

    return _vf[index]._paramCount;
}


int FuncTable::add(const string &name, int entryPoint)
{
	if (name.empty())
		return -1;

	if (find(name) != -1)
		return -1;

	FuncNode temp;
	temp._name = name;
	temp._index = _vf.size();
	temp._entryPoint = entryPoint;
	_vf.push_back(temp);

	return temp._index;
}


int    FuncTable::getlocalDataSize(int index)
{
    if (index < 0 || index >= _vf.size())
        return -1;

    return _vf[index]._localDataSize;
}

int FuncTable::find(const string &name)
{
	for (int i = 0; i < _vf.size(); ++i)
		if (_vf[i]._name == name)
			return i;

	return -1;
}	


int FuncTable::set(const string &name, int paramCount, int localDataSize)
{
	int index = find(name);
	if (index == -1)
		return -1;

	_vf[index]._paramCount = paramCount;
	_vf[index]._localDataSize = localDataSize;
	return 0;
}


void FuncTable::dump()
{
    puts("\n+++++++++++++++++<Function Table Dump>++++++++++++++++++++++++\n");
	printf("Function Number : %d\n\n", _vf.size());
	for (int i = 0; i < _vf.size(); ++i) {
		printf("Name: %s\n", _vf[i]._name.c_str());
		printf("    entryPoint: %d\n", _vf[i]._entryPoint);
		printf("    paramCount: %d\n", _vf[i]._paramCount);
		printf("    localDataSize: %d\n", _vf[i]._localDataSize);
		printf("    index: %d\n\n", _vf[i]._index);
	}
  
    puts("\n+++++++++++++++++<Function Table Dump>++++++++++++++++++++++++\n");
}

void   FuncTable::writeFile(FILE *fp)
{
	int size, t;

	if (fp == NULL)
		return;

	size = _vf.size();
	fwrite(&size, sizeof(size), 1, fp);

	for (int i = 0; i < size; ++i) {
		fwrite(&(_vf[i]._entryPoint), sizeof(int), 1, fp);
		fwrite(&(_vf[i]._paramCount), sizeof(int), 1, fp);
		fwrite(&(_vf[i]._localDataSize), sizeof(int), 1, fp);
		t = _vf[i]._name.size();
		fwrite(&t, sizeof(t), 1, fp);
		fwrite(_vf[i]._name.c_str(), t, 1, fp);
	}
}


int    FuncTable::readFile(FILE *fp)
{
#define FREAD(x, type)  nread = fread(&(x), sizeof(type), 1, fp);\
			if (nread != 1) { \
				fprintf(stderr, "Error! %s %s %d\n", __FILE__, __FUNCTION__, __LINE__); \
				return -1;\
			}

    int nread;
	int size, t;
	char buf[256];

	if (fp == NULL)
		return -1;

	FREAD(size, int);
	_vf.resize(size);

	for (int i = 0; i < size; ++i) {
		FREAD(_vf[i]._entryPoint, int);
		FREAD(_vf[i]._paramCount, int);
		FREAD(_vf[i]._localDataSize, int);
		FREAD(t, int);
		
		if (t >= sizeof(buf))
			printf("function name too long!\n");
		nread = fread(buf, t, 1, fp);
		if (nread != 1)
			return -1;
        buf[t] = '\0';
		_vf[i]._name = buf;
        _vf[i]._index = i;
	}
#undef FREAD
    return 0;
}
